import _ from "lodash";
import $ from "jquery";
import * as DrawUtil from "../../utils/link";
import LinkAnimateUtil from "../../utils/link/link_animate";
const HIGHLIGHT_CLS = "highlight1";

export default class Edge {
  constructor(opts) {
    this.id = _.get(opts, "id");
    this.targetNode = _.get(opts, "targetNode");
    // this._targetType = _.get(opts, '_targetType');
    this.targetEndpoint = _.get(opts, "targetEndpoint");
    this.sourceNode = _.get(opts, "sourceNode");
    // this._sourceType = _.get(opts, '_sourceType');
    this.sourceEndpoint = _.get(opts, "sourceEndpoint");
    // this.type = _.get(opts, 'type', 'endpoint');
    this.orientationLimit = _.get(opts, "orientationLimit");
    // this.shapeType = _.get(opts, 'shapeType', 'Straight');
    // this.hasRadius=_.get(opts, "hasRadius", false),
    // this.label = _.get(opts, 'label');
    // this.arrow = _.get(opts, 'arrow');
    // this.arrowShapeType = _.get(opts, 'arrowShapeType', 'default');
    // this.arrowPosition = _.get(opts, 'arrowPosition', 0.5);
    // this.arrowOffset = _.get(opts, 'arrowOffset', 0),
    // this.labelPosition = _.get(opts, 'labelPosition', 0.5);
    // this.labelOffset = _.get(opts, 'labelOffset', 0),
    this.isExpandWidth = _.get(opts, "isExpandWidth", false);
    this.defaultAnimate = _.get(opts, "defaultAnimate", false);
    this.dom = null;
    // this.labelDom = null;
    // this.arrowDom = null;
    // this.eventHandlerDom = null;
    // this._hasEventListener = false;
    this._coordinateService = null;
    // 鸭子辨识手动判断类型
    this.__type = "edge";
    this._path = null;
    // 业务和库内addEdges写法上有区别，需要兼容
    this.options = _.get(opts, "options") || opts;
    // this._isDeletingEdge = opts._isDeletingEdge;
    // this._global = opts._global;
    // this._on = opts._on;
    // this._emit = opts._emit;
    // 性能优化
    // this._labelWidth = 0;
    // this._labelHeight = 0;
    // 函数节流
    this._updateTimer = null;
    this._UPDATE_INTERVAL = _.get(opts, "labelUpdateInterval", 20);
    // 线段起始位置
    this._sourcePoint = null;
    this._targetPoint = null;
    // 线段的z-index
    this._zIndex = 0;
  }
  _init(obj) {
    if (!this._isInited) {
      if (obj._coordinateService) {
        this._coordinateService = obj._coordinateService;
      }
      this._isInited = true;
      this.dom = this.draw({
        id: this.id,
        dom: this.dom,
        options: this.options,
      });
    }
  }
  draw() {
    let path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path.setAttribute("class", "butterflies-link --base");

    if (this.isExpandWidth) {
      // 扩大线选中范围
      this.eventHandlerDom = document.createElementNS(
        "http://www.w3.org/2000/svg",
        "path"
      );
      this.eventHandlerDom.setAttribute(
        "class",
        "butterflies-link-event-handler"
      );
    }
    return path;
  }
  mounted() {
    if (this.defaultAnimate) {
      this.addAnimate();
    }
  }
  _calcPath(sourcePoint, targetPoint) {
    this._sourcePoint = sourcePoint;
    this._targetPoint = targetPoint;
    let path = DrawUtil.drawAdvancedBezier(sourcePoint, targetPoint);
    // if (this.calcPath) {
    //   path = this.calcPath(sourcePoint, targetPoint);
    // } else if (this.shapeType === 'Bezier') {
    //   path = DrawUtil.drawBezier(sourcePoint, targetPoint);
    // } else if (this.shapeType === 'Straight') {
    //   path = DrawUtil.drawStraight(sourcePoint, targetPoint);
    // } else if (this.shapeType === 'Flow') {
    //   path = DrawUtil.drawFlow(sourcePoint, targetPoint, this.orientationLimit);
    // } else if (this.shapeType === 'Manhattan') {
    //   let obj = DrawUtil.drawManhattan(sourcePoint, targetPoint, {
    //     breakPoints: this._breakPoints,
    //     hasDragged: this._hasDragged,
    //     draggable: this.draggable,
    //     hasRadius: this.hasRadius
    //   });
    //   path = obj.path;
    //   obj.breakPoints[0].type = 'start';
    //   obj.breakPoints[obj.breakPoints.length - 1].type = 'end';
    //   this._breakPoints = obj.breakPoints;
    // } else if (this.shapeType === 'AdvancedBezier') {
    //   path = DrawUtil.drawAdvancedBezier(sourcePoint, targetPoint);
    // } else if (/^Bezier2-[1-3]$/.test(this.shapeType)) {
    //   path = DrawUtil.drawSecondBezier(sourcePoint, targetPoint, this.shapeType);
    // } else if(this.shapeType === 'BrokenLine'){
    //   path = DrawUtil.drawBrokenLine(sourcePoint, targetPoint);
    // }
    this._path = path;
    return path;
  }
  updateHighlight() {
    if (this.sourceNode.actived || this.targetNode.actived) {
      $(this.dom).addClass(HIGHLIGHT_CLS);
      return true;
    } else {
      $(this.dom).removeClass(HIGHLIGHT_CLS);
      return false;
    }
  }
  redraw() {
    if (this.sourceNode.actived || this.targetNode.actived) {
      $(this.dom).addClass(HIGHLIGHT_CLS);
    } else {
      $(this.dom).removeClass(HIGHLIGHT_CLS);
    }
    // 检查线段是否有变化
    let _oldPath = this._path;
    let sourcePoint =
      this.sourceNode.$refs.rightDot &&
      this.getPoint(this.sourceNode.$refs.rightDot, [1, 0]);
    let targetPoint =
      this.targetNode.$refs.leftDot &&
      this.getPoint(this.targetNode.$refs.leftDot, [-1, 0]);
    if (!sourcePoint || !targetPoint) {
      this.dom.removeAttribute("d");
      if (this.isExpandWidth) {
        this.eventHandlerDom.removeAttribute("d");
      }
      return;
    }
    let _newPath = this._calcPath(sourcePoint, targetPoint);
    if (_oldPath === _newPath) {
      return;
    }
    this.dom.setAttribute("d", _newPath);
    if (this.isExpandWidth) {
      this.eventHandlerDom.setAttribute("d", _newPath);
      $(this.eventHandlerDom).insertAfter(this.dom);
    }
    // 函数节流
    if (!this._updateTimer) {
      this._updateTimer = setTimeout(() => {
        // 重新计算动画path
        if (this.animateDom) {
          this.redrawAnimate(_newPath);
        }
        this._updateTimer = null;
      }, this._UPDATE_INTERVAL);
    }

    this.updated && this.updated();
  }
  isConnect() {
    return true;
  }
  addAnimate(options) {
    this.animateDom = LinkAnimateUtil.addAnimate(
      this.dom,
      this._path,
      _.assign(
        {},
        {
          num: 1, // 现在只支持1个点点
          radius: 3,
          color: "#776ef3",
        },
        options
      ),
      this.animateDom
    );
  }
  redrawAnimate() {
    this.animateDom = LinkAnimateUtil.addAnimate(
      this.dom,
      this._path,
      {
        _isContinue: true,
      },
      this.animateDom
    );
  }
  remove() {
    // this.emit('InnerEvents', {
    //   type: 'edge:delete',
    //   data: this
    // });
  }
  setZIndex(index) {
    // this.emit('InnerEvents', {
    //   type: 'edge:setZIndex',
    //   edge: this,
    //   index: index
    // })
  }
  destroy() {
    if (this.eventHandlerDom) {
      $(this.eventHandlerDom).off();
      $(this.eventHandlerDom).remove();
    }
    if (this.animateDom) {
      $(this.animateDom).remove();
    }
    $(this.dom).remove();
  }
  _create(opts) {
    this.id = _.get(opts, "id") || this.id;
    this.targetNode = _.get(opts, "targetNode") || this.targetNode;
    // this._targetType = _.get(opts, '_targetType') || this._targetType;
    this.targetEndpoint = _.get(opts, "targetEndpoint") || this.targetEndpoint;
    this.sourceNode = _.get(opts, "sourceNode") || this.sourceNode;
    // this._sourceType = _.get(opts, '_sourceType') || this._sourceType;
    this.sourceEndpoint = _.get(opts, "sourceEndpoint") || this.sourceEndpoint;
    this.type = _.get(opts, "type") || this.type;
    _.set(this, "options.sourceNode", _.get(this, "sourceNode.id"));
    _.set(this, "options.sourceEndpoint", _.get(this, "sourceEndpoint.id"));
    _.set(this, "options.targetNode", _.get(this, "targetNode.id"));
    _.set(this, "options.targetEndpoint", _.get(this, "targetEndpoint.id"));
    this.redraw();
  }
  getPoint(dom, orientation) {
    let width = $(dom).outerWidth();
    let height = $(dom).outerHeight();

    // 计算锚点起始值
    let left = this._coordinateService._terminal2canvas(
      "x",
      $(dom).offset().left + this._coordinateService.scrollLeft
    );
    let top = this._coordinateService._terminal2canvas(
      "y",
      $(dom).offset().top + this._coordinateService.scrollTop
    );
    return {
      pos: [left + width / 2, top + height / 2],
      orientation,
    };
  }
}
